﻿using System.Management;
using System.Security.Cryptography;
using System.Text;
using Microsoft.Win32;

namespace Mod工具.Util
{
    /// <summary>
    ///     提供安全应用程序工具的静态类。
    /// </summary>
    public static class SafeAppTools
    {
        public static string GamePath = "";
        public static string ModKey = "";

        /// <summary>
        ///     获取CPU的唯一标识符。
        /// </summary>
        /// <returns>CPU的唯一标识符字符串。如果无法获取，则返回"unknown"。</returns>
        public static string GetCpuId()
        {
            try
            {
                string cpuInfo = "";
                var mc = new ManagementClass("Win32_Processor");
                var moc = mc.GetInstances();
                foreach (var o in moc)
                {
                    var mo = (ManagementObject)o;
                    cpuInfo = mo["ProcessorId"].ToString() ?? throw new InvalidOperationException();
                }

                return cpuInfo;
            }
            catch
            {
                return "unknown";
            }
        }

        /// <summary>
        ///     从注册表中读取指定键值。
        /// </summary>
        /// <param name="keyName">注册表键名。</param>
        /// <param name="valueName">注册表值名。</param>
        /// <returns>注册表值的字符串表示。如果读取失败或值不存在，则返回null。</returns>
        private static string? ReadRegistryValue(string keyName, string valueName)
        {
            try
            {
                using var key = Registry.LocalMachine.OpenSubKey(keyName);
                object? value = key?.GetValue(valueName);
                if (value != null)
                {
                    return value.ToString();
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine("Error reading registry value: " + ex.Message);
            }

            return null;
        }

        /// <summary>
        ///     检查应用程序是否已注册。
        /// </summary>
        /// <returns>如果应用程序已注册则返回true，否则返回false。</returns>
        public static bool IsRegistered()
        {
            return ReadRegistryValue(@"SOFTWARE\BH6MOD\Mod管家\AppData", "regInfo") != null;
        }

        /// <summary>
        ///     检查指定的键是否存在于注册表的特定部分，用于检测潜在的窃取行为。
        /// </summary>
        /// <param name="unKey">要检查的注册表键值。</param>
        /// <returns>如果指定键存在，则返回true，否则返回false。</returns>
        public static bool IsEmbezzle(string unKey)
        {
            return ReadRegistryValue(@"SOFTWARE\BH6MOD\Mod管家\Embezzle", unKey) != null;
        }

        /// <summary>
        ///     检查是否能够从注册表中获取游戏路径。
        /// </summary>
        /// <returns>如果成功从注册表中读取到游戏路径，则返回 true；否则返回 false。</returns>
        public static bool IsGetGamePath()
        {
            // 尝试从注册表中读取游戏路径，如果不存在则返回 false
            if (ReadRegistryValue(@"SOFTWARE\BH6MOD\Mod管家\AppData", "gamePath") == null) return false;

            // 成功读取游戏路径后，将其赋值给 GamePath 并返回 true
            string? gmPath = ReadRegistryValue(@"SOFTWARE\BH6MOD\Mod管家\AppData", "gamePath");
            if (gmPath != null)
            {
                GamePath = gmPath;
            }

            return true;
        }


        /// <summary>
        ///     计算输入字符串的SHA256哈希值。
        /// </summary>
        /// <param name="input">要计算哈希值的字符串输入。</param>
        /// <returns>输入字符串的SHA256哈希值，以字符串形式返回。</returns>
        public static string ComputeSha256Hash(string input)
        {
            byte[] inputBytes = Encoding.UTF8.GetBytes(input);
            byte[] hashBytes = SHA256.HashData(inputBytes);

            var builder = new StringBuilder();
            foreach (byte t in hashBytes)
            {
                builder.Append(t.ToString("x2"));
            }

            return builder.ToString();
        }

        /// <summary>
        ///     根据唯一键(unKey)从注册表中获取模组信息。
        /// </summary>
        /// <param name="unKey">模组的唯一标识符。</param>
        /// <returns>包含模组名称和解压密码的ModInfo对象。</returns>
        public static ModInfo GetModData(string unKey)
        {
            // 从注册表读取模组的名称和解压密码，并封装到ModInfo对象中
            var modInfo = new ModInfo
            {
                ModName = ReadRegistryValue($@"SOFTWARE\BH6MOD\Mod管家\AppData\modKey\{unKey}", "modName"),
                ModUnZipPassword =
                    ReadRegistryValue($@"SOFTWARE\BH6MOD\Mod管家\AppData\modKey\{unKey}", "modUnZipPassword")
            };
            return modInfo;
        }

        /// <summary>
        ///     检查指定名称的模组是否存在。
        /// </summary>
        /// <param name="modName">要检查的模组名称。</param>
        /// <returns>如果模组存在，则返回true；否则返回false。</returns>
        public static bool ModExist(string modName)
        {
            // 从注册表读取模组名称对应的键值(modKey)
            string? modKey = ReadRegistryValue($@"SOFTWARE\BH6MOD\Mod管家\AppData\modList\{modName}", "modKey");
            if (modKey == null) return false; // 如果modKey为null，则模组不存在
            ModKey = modKey; // 存储模组的键值
            return true;
        }
    }
}